//
// Created by hps on 24-4-13.
//

#ifndef HTMLCODEHIGHLIGHT_H
#define HTMLCODEHIGHLIGHT_H


#include <QtGui/QSyntaxHighlighter>
#include "HeadFiles.h"

namespace hps {


class HtmlCodeHighLight: public QSyntaxHighlighter {
public:
    HtmlCodeHighLight(QTextDocument *parent = nullptr)
        : QSyntaxHighlighter(parent) {
        setHighLight(parent);;
    }

    void addFormat(QString pattern,
                   Qt::GlobalColor color,
                   bool isBold = false,
                   bool isItailc = false,
                   std::string font = "Ubuntu") {
        QTextCharFormat format;
        if (isBold) {
            format.setFontWeight(QFont::Bold);
        }
        format.setFontItalic(isItailc);
        format.setFontFamily(QString(font.c_str()));
        format.setForeground(color);
        QRegularExpression expression;
        expression.setPattern(pattern);
        m_rules.append({expression, format});
    }

    void setHighLight(QTextDocument *textDocument = nullptr) {
        // 标签
        addFormat(QString("(<html>|</html>)"), Qt::blue);
        addFormat(QString("(<head>|</head>)"), Qt::blue);
        addFormat(QString("(<title>|</title>)"), Qt::blue);
        addFormat(QString("(<body>|</body>)"), Qt::blue);
        addFormat(QString("(<div>|</div>)"), Qt::blue);
        addFormat(QString("(<span>|</span>)"), Qt::blue);
        addFormat(QString("(<p>|</p>)"), Qt::blue);
        addFormat(QString("(<a>|</a>)"), Qt::blue);
        addFormat(QString("(<img>|</img>)"), Qt::blue);
        addFormat(QString("(<ul>|</ul>)"), Qt::blue);
        addFormat(QString("(<ol>|</ol>)"), Qt::blue);
        addFormat(QString("(<li>|</li>)"), Qt::blue);
        addFormat(QString("(<header>|</header>)"), Qt::blue);
        addFormat(QString("(<footer>|</footer>)"), Qt::blue);
        addFormat(QString("(<nav>|</nav>)"), Qt::blue);
        addFormat(QString("(<form>|</form>)"), Qt::blue);
        addFormat(QString("(<input>|</input>)"), Qt::blue);
        addFormat(QString("(<textarea>|</textarea)"), Qt::blue);
        addFormat(QString("<(\\?|/)?([\\w\\-]+)\\s*"), Qt::blue);
        addFormat(QString(">"), Qt::blue);
        addFormat(QString("=\"(.*)\""), Qt::darkGreen);
        // 属性
        addFormat(QString("(\\bhref\\b)"), Qt::red);
        addFormat(QString("(\\bsrc\\b)"), Qt::red);
        addFormat(QString("(\\bid\\b)"), Qt::red);
        addFormat(QString("(\\bclass\\b)"), Qt::red);
        addFormat(QString("(\\bstyle\\b)"), Qt::red);
        addFormat(QString("(\\balt\\b)"), Qt::red);
        addFormat(QString("(\\bwidth\\b)"), Qt::red);
        addFormat(QString("(\\bheight\\b)"), Qt::red);

    }


protected:
    void highlightBlock(const QString &text) override {
        if (text.isEmpty()) {
            return;
        }
        // 对每一行文本应用高亮规则
        for (const HighlightingRule &rule: qAsConst(m_rules)) {
            QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
            while (matchIterator.hasNext()) {
                QRegularExpressionMatch match = matchIterator.next();
                setFormat(match.capturedStart(), match.capturedLength(), rule.format);
            }
        }
    }

private:
    typedef struct _HighlightingRule {
        QRegularExpression pattern;
        QTextCharFormat format;
    } HighlightingRule;

    QVector<HighlightingRule> m_rules;

    QTextCharFormat m_codeBlockFormat;
    QRegularExpression m_commentStartExpression;
    QRegularExpression m_commentEndExpression;
};

} // hps

#endif //HTMLCODEHIGHLIGHT_H
